from django.shortcuts import render
from django.views import View
from django import http
from django_redis import get_redis_connection

from apps.goods.models import SKU

import json
import base64,pickle
# Create your views here.


class CartSelectAllView(View):
    def put(self, request):
        selected = json.loads(request.body.decode()).get('selected', True)

        if not isinstance(selected, bool):
            return http.JsonResponse({'code': 400, 'errmsg': 'selected参数有误'})

        if request.user.is_authenticated:
            user_id = request.user.id
            redis_conn = get_redis_connection('carts')
            sku_dict = redis_conn.hgetall('carts_%s' % user_id)
            sku_ids = sku_dict.keys()
            if selected:
                redis_conn.sadd('selected_%s' % user_id, *sku_ids)
            else:
                redis_conn.srem('selected_%s' % user_id, *sku_ids)
            return http.JsonResponse({'code': 0, 'errmsg': '全选购物车成功'})
        else:
            # {
            #     '<sku_id>': {
            #         'count': '<count>',
            #         'selected': '<selected>',
            #     },
            #     ...
            # }
            cart_str = request.COOKIES.get('carts')
            if cart_str:
                cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
            else:
                cart_dict = {}
            for sku_id in cart_dict.keys():
                cart_dict[sku_id]['selected'] = selected
            cart_data = base64.b64encode(pickle.dumps(cart_dict)).decode()
            response = http.JsonResponse({'code':0, 'errmsg': 'ok'})
            response.set_cookie('carts', cart_data)
            return response


class CartsView(View):
    """
    添POST:/carts/
    查GET:/carts/
    改PUT:/carts/
    删DELETE:/carts/
    """
    def delete(self, request):
        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id')

        if not sku_id:
            return http.JsonResponse({'code': 400, 'errmsg': '缺少必填参数'})
        try:
            SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return http.JsonResponse({'code': 400, 'errmsg': 'sku_id参数有误'})
        if request.user.is_authenticated:
            user_id = request.user.id
            redis_conn = get_redis_connection('carts')
            pl = redis_conn.pipeline()
            pl.hdel('carts_%s' % user_id, sku_id)
            pl.srem('selected_%s' % user_id, sku_id)
            pl.execute()
            return http.JsonResponse({'code': 0, 'errmsg': '删除购物车成功'})
        else:
            cart_str = request.COOKIES.get('carts')
            if cart_str:
                cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
            else:
                cart_dict = {}

            if sku_id in cart_dict:
                del cart_dict[sku_id]
            cookie_str = base64.b64encode(pickle.dumps(cart_dict)).decode()
            response = http.JsonResponse({'code': 0, 'errmsg': 'ok'})
            response.set_cookie('carts', cookie_str)
            return response

    def put(self, request):
        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id')
        count = json_dict.get('count')
        selected = json_dict.get('selected', True)

        if not all([sku_id, count]):
            return http.JsonResponse({'code': 400, 'errmsg': '缺少必填参数'})
        try:
            count = int(count)
        except Exception as e:
            return http.JsonResponse({'code': 400, 'errmsg': 'count参数有误'})
        if not isinstance(selected, bool):
            return http.JsonResponse({'code': 400, 'errmsg': 'selected参数有误'})
        try:
            SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return http.JsonResponse({'code': 400, 'errmsg': 'sku_id参数有误'})

        if request.user.is_authenticated:
            user_id = request.user.id
            redis_conn = get_redis_connection('carts')
            pl = redis_conn.pipeline()
            pl.hset('carts_%s' % user_id, sku_id, count)
            if selected:
                pl.sadd('selected_%s' % user_id, sku_id)
            else:
                pl.srem('selected_%s' % user_id, sku_id)
            pl.execute()
            cart_sku = {
                'id': sku_id,
                'count': count,
                'selected': selected
            }
            return http.JsonResponse({'code': 0, 'errmsg': 'ok', 'cart_sku': cart_sku})
        else:
            cart_str = request.COOKIES.get('carts')
            if cart_str:
                cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
            else:
                cart_dict = {}
            cart_dict[sku_id] = {
                'count': count,
                'selected': selected
            }
            cookie_cart_str = base64.b64encode(pickle.dumps(cart_dict)).decode()

            cart_sku = {
                'id': sku_id,
                'count': count,
                'selected': selected
            }
            response = http.JsonResponse({'code': 0, 'errmsg': 'ok','cart_sku': cart_sku})
            response.set_cookie('carts', cookie_cart_str)
            return response

    def get(self, request):
        user_id = request.user.id
        if request.user.is_authenticated:
            redis_conn = get_redis_connection('carts')
            # hgetall得到一个字典,redis_cart = {b'sku_id':b'count'}
            redis_cart = redis_conn.hgetall('carts_%s' % user_id)
            # semembers得到一个列表， redis_select = [b'sku_id']
            redis_select = redis_conn.smembers('selected_%s' % user_id)

            cart_dict = {}
            for sku_id, count in redis_cart.items():
                cart_dict[int(sku_id)] = {
                    'count': int(count),
                    'selected': sku_id in redis_select
                }
        else:
            cart_str = request.COOKIES.get('carts')
            if cart_str:
                # cart_str_byte = cart_str.encode()
                # cart_dict_byte = base64.b64decode(cart_str_byte)
                # cart_dict = pickle.loads(cart_dict_byte)
                cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
            else:
                cart_dict = {}

        sku_ids = cart_dict.keys()
        skus = SKU.objects.filter(id__in=sku_ids)
        cart_skus = []
        for sku in skus:
            cart_skus.append({
                'id': sku.id,
                'name': sku.name,
                'count': cart_dict.get(sku.id).get('count'),
                'selected': cart_dict.get(sku.id).get('selected'),
                'default_image_url': sku.default_image.url,
                'price': sku.price,
                'amount': sku.price * cart_dict.get(sku.id).get('count'),
            })
        return http.JsonResponse({'code':0, 'errmsg': 'ok', 'cart_skus': cart_skus})


        pass

    def post(self, request):
        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id')
        count = json_dict.get('count')
        selected = json_dict.get('selected', True)

        if not all([sku_id, count]):
            return http.JsonResponse({'code': 400, 'errmsg': '缺少必传参数'})

        try:
            SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return http.JsonResponse({'code': 400, 'errmsg': 'sku_id有误'})

        try:
            count = int(count)
        except Exception as e:
            return http.JsonResponse({'code': 400, 'errmsg': 'count有误'})

        if not isinstance(selected, bool):
            return http.JsonResponse({'code': 400, 'errmsg': 'selected有误'})

        if request.user.is_authenticated:
            user_id = request.user.id
            redis_conn = get_redis_connection('carts')
            pl = redis_conn.pipeline()
            pl.hincrby('carts_%s' % user_id, sku_id, count)
            if selected:
                pl.sadd('selected_%s' % user_id, sku_id)
            pl.execute()
            return http.JsonResponse({'code': 0, 'errmsg': 'ok'})
        else:
            carts_str = request.COOKIES.get('carts')
            if carts_str:
                carts_byte = carts_str.encode()
                carts_dict_byte = base64.b64decode(carts_byte)
                cart_dict = pickle.loads(carts_dict_byte)
            else:
                cart_dict = {}

            # {
            #     '<sku_id>': {
            #         'count': '<count>',
            #         'selected': '<selected>',
            #     },
            #     ...
            # }

            if sku_id in cart_dict:
                origin_count = cart_dict[sku_id]['count']
                count += origin_count
            cart_dict[sku_id]= {
                'count': count,
                'selected': selected
            }

            carts_dict_byte = pickle.dumps(cart_dict)
            carts_str_byte = base64.b64encode(carts_dict_byte)
            cookie_carts_str = carts_str_byte.decode()

            response = http.JsonResponse({'code':0, 'errmsg':'ok'})
            response.set_cookie('carts', cookie_carts_str)
            return response


class CartsSimpleView(View):
    def get(self, request):
        if request.user.is_authenticated:
            redis_conn = get_redis_connection('carts')
            item_dict = redis_conn.hgetall('carts_%s' % request.user.id)
            cart_selected = redis_conn.smembers('selected_%s' % request.user.id)
            cart_dict = {}
            for sku_id, count in item_dict.items():
                cart_dict[int(sku_id)]={
                    'count': int(count),
                    'selected': sku_id in cart_selected
                }
        else:
            cart_str = request.COOKIES.get('carts')
            if cart_str:
                cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
            else:
                cart_dict = {}
        cart_skus = []
        sku_ids = cart_dict.keys()
        skus = SKU.objects.filter(id__in=sku_ids)
        for sku in skus:
            cart_skus.append({
                'id': sku.id,
                'name': sku.name,
                'count': str(cart_dict[sku.id]['count']),
                'default_image_url': sku.default_image.url
            })
        return http.JsonResponse({
            'code': 0,
            'errmsg': 'ok',
            'cart_skus': cart_skus
        })

